﻿package org.utils{
	import flash.display.*;
	import flash.filters.*;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.ByteArray;
	/**
	 * 图片处理类，支持黑白，亮度，对比度，饱和度，单色，柔化，还原，去红眼，魔棒，切图，球面效果
	 * @author Administrator
	 * 
	 */    
	public class ImgEffects_2  {
		public function ImgEffects_2() {
		}
		/**
		 * 黑白效果 
		 * @param child 可视化对象
		 * @return 
		 * 
		 */		
		public static function setGray(child:DisplayObject):void {
			var matrix:Array = [0.33, 0.33, 0.33, 0, 0, 
			     0.33, 0.33, 0.33, 0, 0, 
			     0.33, 0.33, 0.33, 0, 0, 
			     0, 0, 0, 1, 0];
			var filter:ColorMatrixFilter=new ColorMatrixFilter(matrix);
			child.filters=[filter];
		}
		/**
		 * 亮度调节 
		 * @param child 可视化对象
		 * @param val 范围[-100,100]
		 * @return 
		 * 
		 */		
		public static function setBrightness(child:DisplayObject, val:Number):void {
			if (isNaN(val)) {
				return;
			}
			val=limitPara(val);
			var matrix:Array = [1, 0, 0, 0, val, 
			     0, 1, 0, 0, val, 
			     0, 0, 1, 0, val, 
			     0, 0, 0, 1, 0];
			var filter:ColorMatrixFilter=new ColorMatrixFilter(matrix);
			child.filters=[filter];
		}
		
		/**
		 * 对比度 
		 * @param child 可视化对象
		 * @param val 范围[-255,255]
		 * @return 
		 * 
		 */		
		public static function setContrast(child:DisplayObject, val:Number):void {
			if (isNaN(val)) {
				return;
			}
			val=limitPara(val);
			var DELTA_INDEX = [0, 0.01, 0.02, 0.04, 0.05, 0.06, 0.07, 0.08, 0.1, 
			     0.11, 0.12, 0.14, 0.15, 0.16, 0.17, 0.18, 0.2, 
			     0.21, 0.22, 0.24, 0.25, 0.27, 0.28, 
			     0.3, 0.32, 0.34, 0.36, 0.38, 
			     0.4, 0.42, 0.44, 0.46, 0.48, 
			     0.5, 0.53, 0.56, 0.59, 
			     0.62, 0.65, 0.68, 
			     0.71, 0.74, 0.77, 
			     0.8, 0.83, 0.86, 0.89, 
			     0.92, 0.95, 0.98, 
			     1, 1.06, 1.12, 1.18, 1.24, 1.3, 1.36, 1.42, 1.48, 
			     1.54, 1.6, 1.66, 1.72, 1.78, 1.84, 1.9, 1.96, 
			     2, 2.12, 2.25, 2.37, 2.5, 2.62, 2.75, 2.87, 
			     3, 3.2, 3.4, 3.6, 3.8, 4, 4.3, 4.7, 4.9, 5, 5.5, 
			     6, 6.5, 6.8, 7, 7.3, 7.5, 7.8, 8, 8.4, 8.7, 9, 9.4, 9.6, 9.8, 10];
			var diffNum;
			if (val<0) {
				diffNum=127+val/100*127;
			} else {
				diffNum=val%1;
				if (diffNum==0) {
					diffNum=DELTA_INDEX[val];
				} else {
					diffNum = DELTA_INDEX[val << 0] * (1 - diffNum) + DELTA_INDEX[(val << 0) + 1] * diffNum;
				}
				diffNum=diffNum*127+127;
			}
			var matrix:Array = [diffNum / 127, 0, 0, 0, 0.5 * (127 - diffNum), 
			     0, diffNum / 127, 0, 0, 0.5 * (127 - diffNum), 
			     0, 0, diffNum / 127, 0, 0.5 * (127 - diffNum), 
			     0, 0, 0, 1, 0];
			var filter:ColorMatrixFilter=new ColorMatrixFilter(matrix);
			child.filters=[filter];
		}

		/**
		 * 饱和度 
		 * @param child 可视化对象
		 * @param val 范围[-255,255]
		 * @return 
		 * 
		 */		
		public static function setSaturation(child:DisplayObject,val:Number):void {
			if (isNaN(val)) {
				return;
			}
			val=limitPara(val);
			var diffNum =1 + ((val > 0) ? ((3 * val) / 100):(val / 100));
			var rr=0.3086;
			var gg=0.6094;
			var bb=0.082;
			var matrix:Array = [rr * (1 - diffNum) + diffNum, gg * (1 - diffNum), bb * (1 - diffNum), 0, 0, 
			     rr * (1 - diffNum), gg * (1 - diffNum) + diffNum, bb * (1 - diffNum), 0, 0, 
			     rr * (1 - diffNum), gg * (1 - diffNum), bb * (1 - diffNum) + diffNum, 0, 0, 
			     0, 0, 0, 1, 0];
			var filter:ColorMatrixFilter=new ColorMatrixFilter(matrix);
			child.filters=[filter];
		}

		/**
		 * 单色 
		 * @param child 可视化对象
		 * @param val 范围[-255,255]
		 * @return 
		 * 
		 */		
		public static function setHue(child:DisplayObject, val:Number):void {
			val=val/180*Math.PI;
			if (isNaN(val)) {
				return;
			}
			val=limitPara(val);
			var x=Math.cos(val);
			var y=Math.sin(val);
			var rr=0.213;
			var gg=0.715;
			var bb=0.072;
			var matrix:Array =[(rr + (x * (1 - rr))) + (y * ( -rr)), (gg + (x * ( -gg))) + (y * ( -gg)), (bb + (x * ( -bb))) + (y * (1 - bb)), 0, 0, 
			     (rr + (x * ( -rr))) + (y * 0.143), (gg + (x * (1 - gg))) + (y * 0.14), (bb + (x * ( -bb))) + (y * -0.283), 0, 0, 
			     (rr + (x * ( -rr))) + (y * ( -(1 - rr))), (gg + (x * ( -gg))) + (y * gg), (bb + (x * (1 - bb))) + (y * bb), 0, 0, 
			     0, 0, 0, 1, 0];
			var filter:ColorMatrixFilter=new ColorMatrixFilter(matrix);
			child.filters=[filter];
		}
		
		/**
		 * 柔化
		 * @param child 可视化对象
		 * @param val 范围[-255,255]
		 * @return 
		 * 
		 */		
		public static function setBlur(child:DisplayObject, val:Number):void {
			if (isNaN(val)) {
				return;
			}
			val=Math.min(val,255);
			val=Math.max(val,0);
			var blurX:Number=val;
			var blurY:Number=val;
			var filter:BlurFilter=new BlurFilter(blurX,blurY,BitmapFilterQuality.HIGH);
			child.filters=[filter];
		}

		/**
		 * 还原
		 * @param child 可视化对象
		 * @return 
		 * 
		 */
		public static function reset(child:DisplayObject):void {
			var matrix:Array = [1, 0, 0, 0, 0, 
			     0, 1, 0, 0, 0, 
			     0, 0, 1, 0, 0, 
			     0, 0, 0, 1, 0];
			var filter:ColorMatrixFilter=new ColorMatrixFilter(matrix);
			child.filters=[filter];
		}
		
		/**
		 * 去红眼
		 * @param bmd 要处理的图片数据
		 * @param rec 要处理的区域
		 * @return 
		 * 
		 */
		public static function RedEyeReduction(bmd:BitmapData,rec:Rectangle):void {
			bmd.lock();
			for (var i=rec.x-rec.width; i<rec.width+rec.x; i++) {
				for (var j=rec.y-rec.height; j<rec.height+rec.y; j++) {
					var pix:Number=bmd.getPixel(i,j);
					var rr=pix>>>16&255;
					var gg=pix>>>8&255;
					var bb=pix&255;
					var rrr=rr*0.513333;
					var bbb=bb*0.193333;
					var ggg=gg;
					if (rr>=ggg&&rr>=bbb) {
						rr = Math.round((ggg + bbb) / (2 * 0.513333));
						if (rr>255) {
							rr=255;
						} else if (rr < 0) {
							rr=0;
						}
						bmd.setPixel(i, j, rr << 16 | gg << 8 | bb);
					}
				}
			}
			bmd.unlock();
		}
		
		/**
		 * 魔棒 
		 * @param bmd 要处理的图片数据
		 * @param point 魔棒点击坐标
		 * @return 
		 * 
		 */		
		public static function ShapeSelection(bmd:BitmapData,point:Point):void {
			var pix=bmd.getPixel(point.x,point.y);
			var rr=pix>>>16&255;
			var gg=pix>>>8&255;
			var bb=pix&255;
			var rc=10;
			var total:Array=[];
			var testArr:Array=[point];
			var pushArr:Array=[];
			var rememberArr:Array=[];
			while (testArr.length>0) {
				for (i=0; i<testArr.length; i++) {
					var pt=testArr;
					var rightPoint:Point=new Point(pt.x+1,pt.y);
					var downPoint:Point=new Point(pt.x,pt.y+1);
					var leftPoint:Point=new Point(pt.x-1,pt.y);
					var upPoint:Point=new Point(pt.x,pt.y+1);
					checkPoint(rightPoint);
					checkPoint(downPoint);
					checkPoint(leftPoint);
					checkPoint(upPoint);
				}
				total=total.concat(testArr);
				rememberArr=testArr;
				testArr=defoam(pushArr);
				pushArr=[];
			}
			for (i=0; i<total.length; i++) {
				pt=total;
				bmd.setPixel(pt.x,pt.y,0xffffff);
			}

			var bbb:BitmapData=new BitmapData(bmd.width,bmd.height);
			var mmm:Bitmap=new Bitmap(bbb);
			addChild(mmm);
			mmm.x=bm.x;
			mmm.y=bm.y;
			mmm.smoothing=true;
			bm.smoothing=true;
			for (var ii=0; ii<bbb.width; ii++) {
				for (var jj=0; jj<bbb.height; jj++) {
					bbb.setPixel32(ii,jj,0x00ffffff);
				}
			}
			for (i=0; i<total.length; i++) {
				pt=total;
				bbb.setPixel32(pt.x,pt.y,0xa0ff0000);
			}
			mmm.filters=[getBitmapFilter()];
			
			function defoam(arr:Array):Array {
				var arrCopy:Array=[];
				while (arr.length>0) {
					var obj=arr.shift();
					for (var i = 0; i < arr.length; i++) {
						var symbol=arr[i];
						if (obj.x==symbol.x&&obj.y==symbol.y) {
							arr.splice(i,1);
							i--;
						}
					}
					arrCopy.push(obj);
				}
				arr=arrCopy;
				return arr;
			}
			function checkPoint(pt:Point) {
				if (pt.x>bmd.width||pt.y>bmd.height||pt.x<0||pt.y<0) {
					return;
				}
				for (var i=0; i<rememberArr.length; i++) {
					var ptp=rememberArr;
					if (ptp.x==pt.x&&ptp.y==pt.y) {
						return;
					}
				}
				var _pix=bmd.getPixel(pt.x,pt.y);
				var _rr=_pix>>>16&255;
				var _gg=_pix>>>8&255;
				var _bb=_pix&255;
				if (Math.abs(_rr-rr)<rc&&Math.abs(_gg-gg)<rc&&Math.abs(_bb-bb)<rc) {
					pushArr.push(pt);
				}
			}
			function getBitmapFilter():BitmapFilter {
				var color:Number=0xff0000;
				var alpha:Number=0.8;
				var blurX:Number=2;
				var blurY:Number=2;
				var strength:Number=6;
				var inner:Boolean=false;
				var knockout:Boolean=false;
				var quality:Number=BitmapFilterQuality.HIGH;
				return new GlowFilter(color,alpha,blurX,blurY,strength,quality,inner,knockout);
			}
		}
		
		/**
		 * 切图 
		 * @param bmd 要处理的图片数据 
		 * @param rec 要切的区域
		 * @return BitmapData
		 * 
		 */		
		public static function cut(bmd:BitmapData, rec:Rectangle):BitmapData {

			if (rec.x+rec.width<0||rec.y+rec.height<0) {
				return bmd;
			}
			if (rec.x>bmd.width||rec.y>bmd.height) {
				return bmd;
			}

			if (rec.x<0) {
				rec.width+=rec.x;
				rec.x=0;
			}
			if (rec.y<0) {
				rec.height+=rec.y;
				rec.y=0;
			}
			if (rec.x+rec.width>bmd.width) {
				rec.width=bmd.width-rec.x;
			}
			if (rec.y+rec.height>bmd.height) {
				rec.height=bmd.height-rec.y;
			}
			bmd.lock();
			var tempColor:ByteArray=bmd.getPixels(rec);
			
			var bmd_:BitmapData=new BitmapData(rec.width,rec.height,true,0x00FFFF);
			tempColor.position=0;
			bmd_.setPixels(new Rectangle(0, 0, rec.width, rec.height), tempColor);
			bmd.unlock();
			return bmd_;
		}

		/**
		 * 球面效果 
		 * @param source 要处理的图片数据 
		 * @param midx 
		 * @param midy
		 * @return BitmapData
		 * 
		 */		
		public static function spherizeFilter(bmd:BitmapData,p:Point):BitmapData {
			
			var maxp_xy=Math.max(p.x,p.y);
			var radian,radius,offsetX,offsetY,color,r,g,b;
			var bmd=bmd.clone();
			for (var i=0; i<bmd.height-1; i++) {
				for (var j=0; j<bmd.width-1; j++) {
					offsetX=j-p.x;
					offsetY=i-p.y;
					radian=Math.atan2(offsetY,offsetX);
					radius=(offsetX*offsetX+offsetY*offsetY)/maxp_xy
					var x=int(radius*Math.cos(radian))+p.x;
					var y=int(radius*Math.sin(radian))+p.y;
					if (x<0) {
						x=0;
					}
					if (x>=bmd.width) {
						x=bmd.width-1;
					}
					if (y<0) {
						y=0;
					}
					if (y>=bmd.height) {
						y=bmd.height-1;
					}
					color=bmd.getPixel(x,y);
					r = (color & 0xff0000) >> 16;
					g = (color & 0x00ff00) >> 8;
					b=color&0x0000ff;
					bmd.setPixel(j,i,r*65536+g*256+b);
				}
			}
			return bmd;
		}
		
		//限定参数val的取值范围为-100--100之间 
		private static function limitPara(val:Number):Number {
			val=Math.min(val,100);
			val=Math.max(val,-100);
			return val;
		}
		
	}
}